home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / HotkeyPanel.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  14KB  |  659 lines

  1. /*
  2. **    HotkeyPanel.c
  3. **
  4. **    Editing panel for hotkey configuration
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16. enum    {    GAD_TERMTOFRONT=1,GAD_BUFFERTOFRONT,GAD_SKIPDIAL,GAD_ABORTAREXX,
  17.             GAD_PRIORITY,GAD_HOTKEYS,GAD_USE,GAD_LOAD,GAD_SAVE,GAD_CANCEL,
  18.             GAD_DISCARD
  19.         };
  20.  
  21. struct Library *KeymapBase;
  22.  
  23. struct CodeName
  24. {
  25.     ULONG    Code;
  26.     STRPTR    Name;
  27. };
  28.  
  29. STATIC BOOL
  30. GoodCode(STRPTR Code)
  31. {
  32.     IX Expression;
  33.  
  34.     return((BOOL)(ParseIX(Code,&Expression) == 0));
  35. }
  36.  
  37.     /* EditRoutine():
  38.      *
  39.      *    A special string gadget editing routine for key
  40.      *    combination input.
  41.      */
  42.  
  43. STATIC ULONG SAVE_DS ASM
  44. EditRoutine(REG(a0) struct Hook *UnusedHook,REG(a2) struct SGWork *Work,REG(a1) Msg msg)
  45. {
  46.         /* ANSI key codes. */
  47.  
  48.     STATIC struct CodeName KeyTable[] =
  49.     {
  50.         '\r',    "Return",
  51.         '\b',    "Backspace",
  52.         '\033',    "Escape",
  53.         ' ',    "Spacebar",
  54.         ',',    "Comma",
  55.         '\177',    "Delete",
  56.         '\t',    "Tab",
  57.  
  58.         0
  59.     };
  60.  
  61.         /* Special raw key codes */
  62.  
  63.     STATIC struct CodeName RawTable[] =
  64.     {
  65.         CURSOR_UP_CODE,        "Cursor_Up",
  66.         CURSOR_DOWN_CODE,    "Cursor_Down",
  67.         CURSOR_RIGHT_CODE,    "Cursor_Right",
  68.         CURSOR_LEFT_CODE,    "Cursor_Left",
  69.  
  70.         F01_CODE,            "F1",
  71.         F02_CODE,            "F2",
  72.         F03_CODE,            "F3",
  73.         F04_CODE,            "F4",
  74.         F05_CODE,            "F5",
  75.         F06_CODE,            "F6",
  76.         F07_CODE,            "F7",
  77.         F08_CODE,            "F8",
  78.         F09_CODE,            "F9",
  79.         F10_CODE,            "F10",
  80.  
  81.         HELP_CODE,            "Help",
  82.  
  83.         0
  84.     };
  85.  
  86.         /* Qualifier key codes. */
  87.  
  88.     STATIC struct CodeName QualifierTable[] =
  89.     {
  90.         SHIFT_KEY,                "Shift ",
  91.         ALT_KEY,                "Alt ",
  92.         CONTROL_KEY,            "Control ",
  93.         IEQUALIFIER_LCOMMAND,    "LAmiga ",
  94.         IEQUALIFIER_RCOMMAND,    "RAmiga ",
  95.         IEQUALIFIER_LEFTBUTTON,    "Left_Button ",
  96.         IEQUALIFIER_MIDBUTTON,    "Middle_Button ",
  97.         IEQUALIFIER_RBUTTON,    "Right_Button ",
  98.         IEQUALIFIER_NUMERICPAD,    "Numeric_Pad ",
  99.  
  100.         0
  101.     };
  102.  
  103.     ULONG Qualifier;
  104.     UBYTE Key[10];
  105.     STRPTR KeyName;
  106.     LONG KeyLen;
  107.     BOOL GotIt;
  108.     LONG i;
  109.  
  110.     switch(msg->MethodID)
  111.     {
  112.         case SGH_KEY:
  113.  
  114.                 /* If the caps lock key is active, don't change anything */
  115.  
  116.             if(Work->IEvent->ie_Qualifier & IEQUALIFIER_CAPSLOCK)
  117.                 break;
  118.  
  119.                 /* Check for Amiga+Q and Amiga+X. */
  120.  
  121.             if(Work->EditOp == EO_RESET || Work->EditOp == EO_CLEAR)
  122.                 break;
  123.  
  124.                 /* Ditch the qualifier keys */
  125.  
  126.             if(Work->IEvent->ie_Code >= 96 && Work->IEvent->ie_Code <= 103)
  127.             {
  128.                 Work->Actions &= ~(SGA_USE | SGA_BEEP);
  129.                 break;
  130.             }
  131.  
  132.                 /* Strip all the qualifiers we don't want */
  133.  
  134.             Qualifier = Work->IEvent->ie_Qualifier & ~(IEQUALIFIER_REPEAT | IEQUALIFIER_INTERRUPT | IEQUALIFIER_MULTIBROADCAST | IEQUALIFIER_RELATIVEMOUSE);
  135.  
  136.                 /* Clear the translation buffer. */
  137.  
  138.             Key[0] = 0;
  139.  
  140.                 /* Check for raw keys */
  141.  
  142.             GotIt = FALSE;
  143.  
  144.             for(i = 0 ; RawTable[i].Code ; i++)
  145.             {
  146.                 if(Work->IEvent->ie_Code == RawTable[i].Code)
  147.                 {
  148.                     KeyName = RawTable[i].Name;
  149.                     GotIt = TRUE;
  150.  
  151.                     break;
  152.                 }
  153.             }
  154.  
  155.                 /* Translate the code. */
  156.  
  157.             if(!GotIt)
  158.             {
  159.                 struct InputEvent Event;
  160.  
  161.                     /* Make a copy of the input event and */
  162.                     /* clear the qualifier bits */
  163.  
  164.                 CopyMem(Work->IEvent,&Event,sizeof(struct InputEvent));
  165.  
  166.                 Event.ie_Qualifier = NULL;
  167.  
  168.                     /* Translate the event */
  169.  
  170.                 if((KeyLen = MapRawKey(&Event,Key,10,NULL)) < 0)
  171.                     KeyLen = 10;
  172.  
  173.                     /* Did we get anything? */
  174.  
  175.                 if(KeyLen)
  176.                 {
  177.                         /* Carriage return was pressed */
  178.  
  179.                     if(Key[0] == '\r')
  180.                     {
  181.                             /* This probably ends input */
  182.  
  183.                         if(!Qualifier)
  184.                         {
  185.                             Work->Actions = (Work->Actions & ~SGA_BEEP) | SGA_USE | SGA_END;
  186.  
  187.                             break;
  188.                         }
  189.                         else
  190.                         {
  191.                                 /* Is this the enter key? */
  192.  
  193.                             if(Qualifier & IEQUALIFIER_NUMERICPAD)
  194.                             {
  195.                                 KeyName = "Enter";
  196.  
  197.                                 Qualifier &= ~IEQUALIFIER_NUMERICPAD;
  198.  
  199.                                 GotIt = TRUE;
  200.                             }
  201.                         }
  202.                     }
  203.  
  204.                         /* If this is just the tab key, pass it through cleanly */
  205.  
  206.                     if(Key[0] == '\t' && !(Qualifier & ~SHIFT_KEY))
  207.                         break;
  208.  
  209.                         /* Now check for special characters; can't use ToUpper() */
  210.                         /* here since commodities.library will get it dead wrong. */
  211.  
  212.                     if(!GotIt)
  213.                     {
  214.                         for(i = 0 ; KeyTable[i].Code ; i++)
  215.                         {
  216.                             if(KeyTable[i].Code == ToUpper(Key[0]))
  217.                             {
  218.                                 KeyName = KeyTable[i].Name;
  219.  
  220.                                 GotIt = TRUE;
  221.  
  222.                                 break;
  223.                             }
  224.                         }
  225.                     }
  226.  
  227.                         /* If no special character is involved, */
  228.                         /* use the vanilla character code */
  229.  
  230.                     if(!GotIt)
  231.                     {
  232.                         if((Key[0] > ' ' && Key[0] < 127) || Key[0] >= 160)
  233.                         {
  234.                             Key[1] = 0;
  235.  
  236.                             KeyName = Key;
  237.  
  238.                             GotIt = TRUE;
  239.                         }
  240.                     }
  241.                 }
  242.  
  243.                     /* Did we get anything useful? */
  244.  
  245.                 if(!GotIt)
  246.                 {
  247.                     Work->Actions = (Work->Actions & ~SGA_USE) | SGA_BEEP;
  248.  
  249.                     break;
  250.                 }
  251.             }
  252.  
  253.                 /* Take care of the qualifiers. Note that we do not distinguish */
  254.                 /* between the left and right shift/alt keys */
  255.  
  256.             if(Qualifier)
  257.             {
  258.                 LONG MaxChars;
  259.  
  260.                     /* How long the string can get. */
  261.  
  262.                 MaxChars = Work->StringInfo->MaxChars;
  263.  
  264.                     /* Ok, now start building the string */
  265.  
  266.                 Work->WorkBuffer[0] = 0;
  267.  
  268.                 for(i = 0 ; QualifierTable[i].Code ; i++)
  269.                 {
  270.                     if(Qualifier & QualifierTable[i].Code)
  271.                         LimitedStrcat(MaxChars,Work->WorkBuffer,QualifierTable[i].Name);
  272.                 }
  273.  
  274.                     /* Add the key itself */
  275.  
  276.                 LimitedStrcat(MaxChars,Work->WorkBuffer,KeyName);
  277.  
  278.                     /* Update the work data */
  279.  
  280.                 Work->NumChars    = strlen(Work->WorkBuffer);
  281.                 Work->BufferPos    = Work->NumChars;
  282.  
  283.                     /* Finished... */
  284.  
  285.                 Work->Actions = (Work->Actions & ~(SGA_BEEP | SGA_PREVACTIVE | SGA_NEXTACTIVE | SGA_END)) | SGA_REDISPLAY | SGA_USE;
  286.             }
  287.             else
  288.                 Work->Actions &= ~(SGA_USE | SGA_BEEP);
  289.  
  290.             break;
  291.  
  292.         case SGH_CLICK:
  293.  
  294.             break;
  295.  
  296.         default:
  297.  
  298.             return(FALSE);
  299.     }
  300.  
  301.     return(TRUE);
  302. }
  303.  
  304. BOOL
  305. HotkeyPanelConfig(struct Configuration *LocalConfig,struct Hotkeys *Hotkeys,STRPTR LastKeys,BOOL *ChangePtr)
  306. {
  307.     STATIC struct Hook EditHook;
  308.  
  309.     struct Hotkeys *PrivateHotkeys;
  310.     struct LayoutHandle    *Handle;
  311.     BOOL Changed = FALSE;
  312.  
  313.     if(!(PrivateHotkeys = (struct Hotkeys *)AllocVecPooled(sizeof(struct Hotkeys),MEMF_ANY)))
  314.     {
  315.         DisplayBeep(NULL);
  316.         return(FALSE);
  317.     }
  318.  
  319.     CopyMem(Hotkeys,PrivateHotkeys,sizeof(struct Hotkeys));
  320.  
  321.     InitHook(&EditHook,(HOOKFUNC)EditRoutine,NULL);
  322.  
  323.     KeymapBase = OpenLibrary("keymap.library",0);
  324.  
  325.     if(Handle = LT_CreateHandleTags(Window->WScreen,
  326.         LAHN_LocaleHook,    &LocaleHook,
  327.         LAHN_ExitFlush,    FALSE,
  328.     TAG_DONE))
  329.     {
  330.         struct Window *PanelWindow;
  331.  
  332.         LT_New(Handle,
  333.             LA_Type,    VERTICAL_KIND,
  334.         TAG_DONE);
  335.         {
  336.             LT_New(Handle,
  337.                 LA_Type,    VERTICAL_KIND,
  338.                 LA_LabelID,    MSG_V36_0083,
  339.             TAG_DONE);
  340.             {
  341.                 LT_New(Handle,
  342.                     LA_Type,        STRING_KIND,
  343.                     LA_LabelID,        MSG_HOTKEYPANEL_TERM_SCREEN_TO_FRONT_GAD,
  344.                     LA_STRPTR,        PrivateHotkeys->termScreenToFront,
  345.                     LA_Chars,        30,
  346.                     GTST_MaxChars,    sizeof(PrivateHotkeys->termScreenToFront) - 1,
  347.                     LA_ID,            GAD_TERMTOFRONT,
  348.  
  349.                     KeymapBase ? GTST_EditHook : TAG_IGNORE,&EditHook,
  350.                 TAG_DONE);
  351.  
  352.                 LT_New(Handle,
  353.                     LA_Type,        STRING_KIND,
  354.                     LA_LabelID,        MSG_HOTKEYPANEL_BUFFER_SCREEN_TO_FRONT_GAD,
  355.                     LA_STRPTR,        PrivateHotkeys->BufferScreenToFront,
  356.                     GTST_MaxChars,    sizeof(PrivateHotkeys->BufferScreenToFront) - 1,
  357.                     LA_ID,            GAD_BUFFERTOFRONT,
  358.  
  359.                     KeymapBase ? GTST_EditHook : TAG_IGNORE,&EditHook,
  360.                 TAG_DONE);
  361.  
  362.                 LT_New(Handle,
  363.                     LA_Type,        STRING_KIND,
  364.                     LA_LabelID,        MSG_HOTKEYPANEL_SKIP_DIAL_ENTRY_GAD,
  365.                     LA_STRPTR,        PrivateHotkeys->SkipDialEntry,
  366.                     GTST_MaxChars,    sizeof(PrivateHotkeys->SkipDialEntry) - 1,
  367.                     LA_ID,            GAD_SKIPDIAL,
  368.  
  369.                     KeymapBase ? GTST_EditHook : TAG_IGNORE,&EditHook,
  370.                 TAG_DONE);
  371.  
  372.                 LT_New(Handle,
  373.                     LA_Type,        STRING_KIND,
  374.                     LA_LabelID,        MSG_HOTKEYPANEL_ABORT_AREXX_GAD,
  375.                     LA_STRPTR,        PrivateHotkeys->AbortARexx,
  376.                     GTST_MaxChars,    sizeof(PrivateHotkeys->AbortARexx) - 1,
  377.                     LA_ID,            GAD_ABORTAREXX,
  378.  
  379.                     KeymapBase ? GTST_EditHook : TAG_IGNORE,&EditHook,
  380.                 TAG_DONE);
  381.  
  382.                 LT_EndGroup(Handle);
  383.             }
  384.  
  385.             LT_New(Handle,
  386.                 LA_Type,        VERTICAL_KIND,
  387.                 LA_LabelID,        MSG_V36_0084,
  388.             TAG_DONE);
  389.             {
  390.                 LT_New(Handle,
  391.                     LA_Type,            SliderType,
  392.                     LA_LabelID,            MSG_HOTKEYPANEL_COMMODITY_PRIORITY_GAD,
  393.                     LA_BYTE,            &PrivateHotkeys->CommodityPriority,
  394.                     GTSL_Min,            -128,
  395.                     GTSL_Max,            127,
  396.                     GTSL_LevelFormat,    "%4ld",
  397.                     LA_Chars,            16,
  398.                     LA_ID,                GAD_PRIORITY,
  399.                 TAG_DONE);
  400.  
  401.                 LT_New(Handle,
  402.                     LA_Type,    CHECKBOX_KIND,
  403.                     LA_LabelID,    MSG_HOTKEYPANEL_HOTKEYS_ENABLED_GAD,
  404.                     LA_BYTE,    &PrivateHotkeys->HotkeysEnabled,
  405.                     LA_ID,        GAD_HOTKEYS,
  406.                 TAG_DONE);
  407.  
  408.                 LT_EndGroup(Handle);
  409.             }
  410.  
  411.             LT_New(Handle,
  412.                 LA_Type,VERTICAL_KIND,
  413.             TAG_DONE);
  414.             {
  415.                 LT_New(Handle,
  416.                     LA_Type,        XBAR_KIND,
  417.                     LAXB_FullSize,    TRUE,
  418.                 TAG_DONE);
  419.  
  420.                 LT_EndGroup(Handle);
  421.             }
  422.  
  423.             LT_New(Handle,LA_Type,HORIZONTAL_KIND,
  424.                 LAGR_SameSize,    TRUE,
  425.                 LAGR_Spread,    TRUE,
  426.             TAG_DONE);
  427.             {
  428.                 LT_New(Handle,
  429.                     LA_Type,        BUTTON_KIND,
  430.                     LA_LabelID,        MSG_GLOBAL_USE_GAD,
  431.                     LA_ID,            GAD_USE,
  432.                     LABT_ReturnKey,    TRUE,
  433.                     LABT_ExtraFat,    TRUE,
  434.                 TAG_DONE);
  435.  
  436.                 LT_New(Handle,
  437.                     LA_Type,        BUTTON_KIND,
  438.                     LA_LabelID,        MSG_GLOBAL_LOAD_GAD,
  439.                     LA_ID,            GAD_LOAD,
  440.                 TAG_DONE);
  441.  
  442.                 LT_New(Handle,
  443.                     LA_Type,        BUTTON_KIND,
  444.                     LA_LabelID,        MSG_GLOBAL_SAVE_GAD,
  445.                     LA_ID,            GAD_SAVE,
  446.                 TAG_DONE);
  447.  
  448.                 LT_New(Handle,
  449.                     LA_Type,        BUTTON_KIND,
  450.                     LA_LabelID,        MSG_DISCARD_GAD,
  451.                     LA_ID,            GAD_DISCARD,
  452.                 TAG_DONE);
  453.  
  454.                 LT_New(Handle,
  455.                     LA_Type,        BUTTON_KIND,
  456.                     LA_LabelID,        MSG_GLOBAL_CANCEL_GAD,
  457.                     LA_ID,            GAD_CANCEL,
  458.                     LABT_EscKey,    TRUE,
  459.                 TAG_DONE);
  460.  
  461.                 LT_EndGroup(Handle);
  462.             }
  463.  
  464.             LT_EndGroup(Handle);
  465.         }
  466.  
  467.         if(PanelWindow = LT_Build(Handle,
  468.             LAWN_TitleID,        MSG_HOTKEYPANEL_HOTKEY_PREFERENCES_TXT,
  469.             LAWN_HelpHook,        &GuideHook,
  470.             LAWN_Parent,        Window,
  471.             WA_DepthGadget,        TRUE,
  472.             WA_DragBar,            TRUE,
  473.             WA_RMBTrap,            TRUE,
  474.             WA_Activate,        TRUE,
  475.             WA_SimpleRefresh,    TRUE,
  476.         TAG_DONE))
  477.         {
  478.             struct IntuiMessage    *Message;
  479.             BOOL Done = FALSE;
  480.             ULONG MsgClass;
  481.             struct Gadget *MsgGadget;
  482.             struct FileRequester *FileRequest;
  483.             UBYTE DummyBuffer[MAX_FILENAME_LENGTH];
  484.             STRPTR String;
  485.  
  486.             GuideContext(CONTEXT_HOTKEYS);
  487.  
  488.             PushWindow(PanelWindow);
  489.  
  490.             do
  491.             {
  492.                 if(Wait(PORTMASK(PanelWindow->UserPort) | SIG_BREAK) & SIG_BREAK)
  493.                 {
  494.                     Changed = FALSE;
  495.                     break;
  496.                 }
  497.  
  498.                 while(Message = (struct IntuiMessage *)LT_GetIMsg(Handle))
  499.                 {
  500.                     MsgClass    = Message->Class;
  501.                     MsgGadget    = (struct Gadget *)Message->IAddress;
  502.  
  503.                     LT_ReplyIMsg(Message);
  504.  
  505.                     if(MsgClass == IDCMP_GADGETUP)
  506.                     {
  507.                         switch(MsgGadget->GadgetID)
  508.                         {
  509.                             case GAD_TERMTOFRONT:
  510.                             case GAD_BUFFERTOFRONT:
  511.                             case GAD_SKIPDIAL:
  512.                             case GAD_ABORTAREXX:
  513.  
  514.                                 String = LT_GetString(Handle,MsgGadget->GadgetID);
  515.  
  516.                                 if(!GoodCode(String))
  517.                                 {
  518.                                     DisplayBeep(PanelWindow->WScreen);
  519.  
  520.                                     LT_Activate(Handle,MsgGadget->GadgetID);
  521.                                 }
  522.  
  523.                                 break;
  524.  
  525.                             case GAD_USE:
  526.  
  527.                                 LT_UpdateStrings(Handle);
  528.  
  529.                                 CopyMem(PrivateHotkeys,Hotkeys,sizeof(struct Hotkeys));
  530.  
  531.                                 Changed = TRUE;
  532.  
  533.                                 if(ChangePtr)
  534.                                     *ChangePtr = TRUE;
  535.  
  536.                                 Done = TRUE;
  537.                                 break;
  538.  
  539.                             case GAD_DISCARD:
  540.  
  541.                                 if(ChangePtr)
  542.                                     *ChangePtr = FALSE;
  543.  
  544.                                 LastKeys[0] = 0;
  545.                                 Changed = Done = TRUE;
  546.  
  547.                                 if(LocalConfig)
  548.                                     strcpy(LocalConfig->HotkeyFileName,LastKeys);
  549.  
  550.                                 break;
  551.  
  552.                             case GAD_CANCEL:
  553.  
  554.                                 Changed = FALSE;
  555.                                 Done = TRUE;
  556.                                 break;
  557.  
  558.                             case GAD_LOAD:
  559.  
  560.                                 LT_LockWindow(PanelWindow);
  561.  
  562.                                 strcpy(DummyBuffer,LastKeys);
  563.  
  564.                                 if(FileRequest = OpenSingleFile(PanelWindow,LocaleString(MSG_HOTKEYPANEL_LOAD_HOTKEYS_TXT),NULL,"#?.prefs",DummyBuffer,sizeof(DummyBuffer)))
  565.                                 {
  566.                                     FreeAslRequest(FileRequest);
  567.  
  568.                                     if(!LoadHotkeys(DummyBuffer,PrivateHotkeys))
  569.                                         ShowError(PanelWindow,ERR_LOAD_ERROR,IoErr(),DummyBuffer);
  570.                                     else
  571.                                     {
  572.                                         strcpy(LastKeys,DummyBuffer);
  573.  
  574.                                         if(LocalConfig)
  575.                                             strcpy(LocalConfig->HotkeyFileName,LastKeys);
  576.  
  577.                                         LT_SetAttributes(Handle,GAD_TERMTOFRONT,
  578.                                             GTST_String,PrivateHotkeys->termScreenToFront,
  579.                                         TAG_DONE);
  580.  
  581.                                         LT_SetAttributes(Handle,GAD_BUFFERTOFRONT,
  582.                                             GTST_String,PrivateHotkeys->BufferScreenToFront,
  583.                                         TAG_DONE);
  584.  
  585.                                         LT_SetAttributes(Handle,GAD_SKIPDIAL,
  586.                                             GTST_String,PrivateHotkeys->SkipDialEntry,
  587.                                         TAG_DONE);
  588.  
  589.                                         LT_SetAttributes(Handle,GAD_ABORTAREXX,
  590.                                             GTST_String,PrivateHotkeys->AbortARexx,
  591.                                         TAG_DONE);
  592.  
  593.                                         LT_SetAttributes(Handle,GAD_PRIORITY,
  594.                                             GTSL_Level,PrivateHotkeys->CommodityPriority,
  595.                                         TAG_DONE);
  596.  
  597.                                         LT_SetAttributes(Handle,GAD_HOTKEYS,
  598.                                             GTCB_Checked,PrivateHotkeys->HotkeysEnabled,
  599.                                         TAG_DONE);
  600.  
  601.                                         Changed = TRUE;
  602.  
  603.                                         if(ChangePtr)
  604.                                             *ChangePtr = FALSE;
  605.                                     }
  606.                                 }
  607.  
  608.                                 LT_UnlockWindow(PanelWindow);
  609.  
  610.                                 break;
  611.  
  612.                             case GAD_SAVE:
  613.  
  614.                                 LT_LockWindow(PanelWindow);
  615.  
  616.                                 LT_UpdateStrings(Handle);
  617.  
  618.                                 strcpy(DummyBuffer,LastKeys);
  619.  
  620.                                 if(FileRequest = SaveFile(PanelWindow,LocaleString(MSG_HOTKEYPANEL_SAVE_HOTKEYS_TXT),NULL,"#?.prefs",DummyBuffer,sizeof(DummyBuffer)))
  621.                                 {
  622.                                     FreeAslRequest(FileRequest);
  623.  
  624.                                     if(!WriteIFFData(DummyBuffer,PrivateHotkeys,sizeof(struct Hotkeys),ID_HOTK))
  625.                                         ShowError(PanelWindow,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  626.                                     else
  627.                                     {
  628.                                         strcpy(LastKeys,DummyBuffer);
  629.  
  630.                                         if(LocalConfig)
  631.                                             strcpy(LocalConfig->HotkeyFileName,LastKeys);
  632.  
  633.                                         if(ChangePtr)
  634.                                             *ChangePtr = FALSE;
  635.                                     }
  636.                                 }
  637.  
  638.                                 LT_UnlockWindow(PanelWindow);
  639.  
  640.                                 break;
  641.                         }
  642.                     }
  643.                 }
  644.             }
  645.             while(!Done);
  646.  
  647.             PopWindow();
  648.         }
  649.  
  650.         LT_DeleteHandle(Handle);
  651.     }
  652.  
  653.     FreeVecPooled(PrivateHotkeys);
  654.  
  655.     CloseLibrary(KeymapBase);
  656.  
  657.     return(Changed);
  658. }
  659.